use crate::{LineCommand, LineSegment, Point};


#[derive(Clone, Debug, PartialEq)]
pub struct Polygon {
	pub vertices: Vec<Point>,
}
impl Polygon {
	pub fn edges(&self) -> Edges {
		Edges {
			first_vertex: self.vertices.first(),
			vertex_iter: self.vertices[1..].iter(),
			last_vertex: self.vertices.first(),
		}
	}
}
#[derive(Clone, Debug)]
pub struct Edges<'a> {
	first_vertex: Option<&'a Point>,
	vertex_iter: core::slice::Iter<'a, Point>,
	last_vertex: Option<&'a Point>,
}
impl<'a> Iterator for Edges<'a> {
	type Item = LineSegment;

	fn next(&mut self) -> Option<Self::Item> {
		if let Some(vertex) = self.vertex_iter.next() {
			let first_vertex = self.first_vertex.replace(vertex).unwrap();
			return Some(LineSegment::new(*first_vertex, *vertex));
		}
		if let Some(vertex) = self.last_vertex.take() {
			let first_vertex = self.first_vertex.take().unwrap();
			return Some(LineSegment::new(*first_vertex, *vertex));
		}
		None
	}
}

impl Polygon {
	pub fn commands(&self) -> Commands {
		Commands {
			pos: 0,
			polygon: self,
			move_to: LineCommand::MoveTo(self.vertices.first().copied().unwrap()),
			close: LineCommand::Close,
		}
	}
}
pub struct Commands<'a> {
	pos: usize,
	polygon: &'a Polygon,
	move_to: LineCommand,
	close: LineCommand,
}
impl<'a> Iterator for Commands<'a> {
	type Item = LineCommand;
	fn next(&mut self) -> Option<Self::Item> {
		self.pos += 1;
		if self.pos == 1 {
			Some(self.move_to)
		} else if self.pos - 1 < self.polygon.vertices.len() {
			self.polygon.vertices.get(self.pos - 1).map(|v| LineCommand::LineTo(*v))
		} else if self.pos - 1 == self.polygon.vertices.len() {
			Some(self.close)
		} else {
			None
		}
	}
}
